/*
 * @lc app=leetcode.cn id=318 lang=cpp
 *
 * [318] 最大单词长度乘积
 */

// @lc code=start
#include <bits/stdc++.h>
using namespace std;
class Solution
{
public:
    inline long long toLongLong(char c)
    {
        return (long long)1 << (int)(c - 'a');
    }
    inline long long toLongLong(string &word)
    {
        long long ret = 0;
        for (auto c : word)
        {
            ret |= toLongLong(c);
        }

        ret |= ((long long)word.length()) << 26;
        return ret;
    }
    inline long long getLength(long long w)
    {
        return w >> 26;
    }
    inline long long low26(long long w)
    {
        return w & (((long long)1 << 26) - 1);
    }
    inline bool existSameChar(long long w1, long long w2)
    {
        return low26(w1) & low26(w2);
    }
    int maxProduct(vector<string> &words)
    {
        /**
         * 使用二进制表示一个字符串。字符串的最低位表示'a'，倒数第二低位表示'b'
         *
         * 26 个小写英文字母仅占26个位，按照题目要求，每个字符串的长度不超过 1000，
         * 因此可以使用高 位高（64 - 26）位表示字符串的长度
         */
        vector<long long> ws;
        for (auto &s : words)
        {
            ws.push_back(toLongLong(s));
        }

        long long ans = 0;

        for(int i = 0; i < ws.size(); i++)
        {
            for(int j = i + 1; j < ws.size(); j++)
            {
                if(!existSameChar(ws[i], ws[j]))
                {
                    ans = max(ans, getLength(ws[i]) * getLength(ws[j]));
                }
            }
        }

        return ans;
    }
};
// @lc code=end
